﻿using System.Net;
using System.Net.Mail;

namespace Devonline.Utils;

/// <summary>
/// SMTP send email
/// </summary>
public class SmtpMail
{
    /// <summary>
    /// 邮件服务器地址
    /// </summary>
    public string? Host { get; set; }
    /// <summary>
    /// 邮件服务器端口号
    /// </summary>
    public int Port { get; set; }
    /// <summary>
    /// 发件人/发件地址
    /// </summary>
    public string? From { get; set; }
    /// <summary>
    /// 接收人/接受地址
    /// </summary>
    public string? To { get; set; }
    /// <summary>
    /// 抄送/抄送地址
    /// </summary>
    public string? CC { get; set; }
    /// <summary>
    /// 密送/密送地址
    /// </summary>
    public string? Bcc { get; set; }
    /// <summary>
    /// 邮件主题
    /// </summary>
    public string? Subject { get; set; }
    /// <summary>
    /// 邮件正文
    /// </summary>
    public string? Body { get; set; }
    /// <summary>
    /// 邮件内容是否 HTML 格式
    /// </summary>
    public bool IsHtml { get; set; }
    /// <summary>
    /// 附件列表
    /// </summary>
    public string? AttachmentFileNames { get; set; }
    /// <summary>
    /// 是否需要认证
    /// </summary>
    public bool UseCredentials { get; set; }
    /// <summary>
    /// 用户名
    /// </summary>
    public string? UserName { get; set; }
    /// <summary>
    /// 密码
    /// </summary>
    public string? Password { get; set; }

    /// <summary>
    /// Send an email
    /// <paramref name="userToken"/>
    /// </summary>
    public void Send(object? userToken = null)
    {
        if (string.IsNullOrWhiteSpace(Host))
        {
            throw new ArgumentNullException(nameof(Host), "缺少必须的邮件服务器地址");
        }

        if (string.IsNullOrWhiteSpace(From))
        {
            throw new ArgumentNullException(nameof(From), "缺少必须的发件人");
        }

        if (string.IsNullOrWhiteSpace(To))
        {
            throw new ArgumentNullException(nameof(To), "缺少必须的接收人");
        }

        if (Port <= 0 || Port > 65535)
        {
            Port = 25;
        }

        using var smtpClient = new SmtpClient(Host, Port);
        using var mailMessage = new MailMessage
        {
            From = new MailAddress(From),
            Body = Body,
            Subject = Subject,
            IsBodyHtml = IsHtml
        };

        if (!string.IsNullOrWhiteSpace(To))
        {
            foreach (string to in To.Split(AppSettings.CHAR_SEMICOLON, StringSplitOptions.RemoveEmptyEntries))
            {
                mailMessage.To.Add(to);
            }
        }

        if (!string.IsNullOrWhiteSpace(CC))
        {
            foreach (string cc in CC.Split(AppSettings.CHAR_SEMICOLON, StringSplitOptions.RemoveEmptyEntries))
            {
                mailMessage.CC.Add(cc);
            }
        }

        if (!string.IsNullOrWhiteSpace(Bcc))
        {
            foreach (string bcc in Bcc.Split(AppSettings.CHAR_SEMICOLON, StringSplitOptions.RemoveEmptyEntries))
            {
                mailMessage.Bcc.Add(bcc);
            }
        }

        if (!string.IsNullOrWhiteSpace(AttachmentFileNames))
        {
            foreach (string attachment in AttachmentFileNames.Split(AppSettings.CHAR_SEMICOLON, StringSplitOptions.RemoveEmptyEntries))
            {
                mailMessage.Attachments.Add(new Attachment(attachment));
            }
        }

        if (UseCredentials && !string.IsNullOrWhiteSpace(UserName) && !string.IsNullOrWhiteSpace(Password))
        {
            smtpClient.Credentials = new NetworkCredential(UserName, Password);
        }

        smtpClient.SendAsync(mailMessage, userToken);
    }
}